using System.Diagnostics;

namespace CondaManager;

public partial class Form1 : Form
{
    private bool _configured;
    public class CondaCheckThread(Form1 f)
    {
        private Form1 Object { get; } = f;

        public void Recheck()
        {
            Object._configured = false;
            Object.recheckButton.Enabled = false;
            Object.statusTextBox.Text = "正在检测……";
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/C conda --version";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            if (process.Start())
            {
                string output = process.StandardOutput.ReadToEnd().Trim();
                process.WaitForExit();
                process.Close();
                if (output.Contains("conda"))
                {
                    Object.statusTextBox.Text = "已配置";
                    Object._configured = true;
                }
                else
                {
                    Object.recheckButton.Enabled = true;
                    Object.statusTextBox.Text = "未配置";
                }
            }
            else
            {
                Object.recheckButton.Enabled = true;
                Object.statusTextBox.Text = "未配置";
            }
        }
    }
    public class MirrorThread(Form1 f)
    {
        private Form1 Object { get; } = f;
        public string? MirrorUrl { get; init; }
        
        public void AddMirrorUrl()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.mirrorTextBox.Enabled = false;
            Object.mirrorTextBox.Text = "";
            Object.addMirrorButton.Enabled = false;
            Object.addMirrorButton.Text = "正在添加……";
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = $"/C conda config --add channels {this.MirrorUrl}";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            if (process.Start())
            {
                process.WaitForExit();
                process.Close();
                Object.mirrorTextBox.Enabled = true;
                Object.addMirrorButton.Enabled = true;
                Object.addMirrorButton.Text = "添加该镜像";
            }
        }
        public void RemoveMirrorUrl()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.mirrorsListBox.Enabled = false;
            Object.recheckMirrorsButton.Enabled = false;
            Object.removeMirrorButton.Enabled = false;
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = $"/C conda config --remove channels {this.MirrorUrl}";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            if (process.Start())
            {
                process.WaitForExit();
                process.Close();
                Object.mirrorsListBox.Enabled = true;
                Object.recheckMirrorsButton.Enabled = true;
                Object.removeMirrorButton.Enabled = true;
            }
        }
    }
    public class CondaEnvsThread(Form1 f)
    {
        private Form1 Object { get; } = f;
        public string? EnvName { get; init; }
        public string? PythonVersion { get; init; }

        public void ShowMirrorsText()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.recheckMirrorsButton.Enabled = false;
            Object.mirrorsListBox.Enabled = false;
            Object.mirrorsListBox.Items.Clear();
            Object.mirrorsListBox.Items.Add("正在检测……");
            Object.removeMirrorButton.Enabled = false;
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/C conda config --show channels";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            if (process.Start())
            {
                string? output = process.StandardOutput.ReadLine();
                Object.mirrorsListBox.Items.Clear();
                while (output != null && output.Trim().Length > 0)
                {
                    output = output.Trim();
                    if (!output.StartsWith('-'))
                    {
                        output = process.StandardOutput.ReadLine();
                        continue;
                    }

                    string item = output.Split(" ", StringSplitOptions.RemoveEmptyEntries)[1];
                    Object.mirrorsListBox.Items.Add(item);
                    output = process.StandardOutput.ReadLine();
                }
                process.WaitForExit();
                process.Close();
                Object.recheckMirrorsButton.Enabled = true;
                Object.mirrorsListBox.Enabled = true;
                Object.removeMirrorButton.Enabled = true;
            }
        }
        public void Recheck()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.recheckEnvs.Enabled = false;
            Object.envsListBox.Items.Clear();
            Object.envsListBox.Items.Add("正在检测……");
            Object.envsListBox.Enabled = false;
            Object.removeEnvButton.Enabled = false;
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/C conda info --envs";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = true;
            if (process.Start())
            {
                string? output = process.StandardOutput.ReadLine();
                Object.envsListBox.Items.Clear();
                while (output != null && output.Trim().Length > 0)
                {
                    if (output.StartsWith('#'))
                    {
                        output = process.StandardOutput.ReadLine();
                        continue;
                    }

                    string item = output.Trim().Split(" ", StringSplitOptions.RemoveEmptyEntries)[0];
                    Object.envsListBox.Items.Add(item);
                    output = process.StandardOutput.ReadLine();
                }
                process.WaitForExit();
                process.Close();
                Object.recheckEnvs.Enabled = true;
                Object.envsListBox.Enabled = true;
                Object.removeEnvButton.Enabled = true;
            }
        }
        public void DeleteEnv()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.recheckEnvs.Enabled = false;
            Object.envsListBox.Enabled = false;
            Object.removeEnvButton.Enabled = false;
            Object.removeEnvButton.Text = "正在删除……";
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = $"/C conda remove -n {this.EnvName} --all";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardInput = true;
            if (process.Start())
            {
                process.StandardInput.Write("y\ny\n");
                process.WaitForExit();
                process.Close();
                Object.recheckEnvs.Enabled = true;
                Object.envsListBox.Enabled = true;
                Object.removeEnvButton.Enabled = true;
                Object.removeEnvButton.Text = "删除";
            }
        }
        public void AddEnv()
        {
            if (!Object._configured)
            {
                return;
            }
            Object.envNameTextBox.Enabled = false;
            Object.pythonVersionTextBox.Enabled = false;
            Object.addEnvButton.Enabled = false;
            Object.addEnvButton.Text = "正在添加……";
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = $"/C conda create --name {this.EnvName} python={this.PythonVersion}";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardInput = true;
            if (process.Start())
            {
                process.StandardInput.Write("y\n");
                process.WaitForExit();
                process.Close();
                Object.envNameTextBox.Enabled = true;
                Object.pythonVersionTextBox.Enabled = true;
                Object.addEnvButton.Enabled = true;
                Object.addEnvButton.Text = "添加";
            }
        }
    }
    public Form1()
    {
        InitializeComponent();
    }

    private void Recheck()
    {
        CondaCheckThread condaCheck = new CondaCheckThread(this);
        Thread thread = new Thread(condaCheck.Recheck);
        thread.Start();
        thread.Join();
    }

    private void ShowMirrorsText()
    {
        CondaEnvsThread condaEnvs = new CondaEnvsThread(this);
        Thread thread = new Thread(condaEnvs.ShowMirrorsText);
        thread.Start();
        thread.Join();
        this.mirrorTextBox.Enabled = true;
        this.addMirrorButton.Enabled = true;
    }

    private void AddMirrorUrl()
    {
        MirrorThread mirror = new MirrorThread(this)
        {
            MirrorUrl = this.mirrorTextBox.Text
        };
        Thread thread = new Thread(mirror.AddMirrorUrl);
        thread.Start();
        thread.Join();
    }

    private void RemoveMirrorUrl(string? mirrorUrl)
    {
        MirrorThread mirror = new MirrorThread(this)
        {
            MirrorUrl = mirrorUrl
        };
        Thread thread = new Thread(mirror.RemoveMirrorUrl);
        thread.Start();
        thread.Join();
    }

    private void EnvListRefresh()
    {
        CondaEnvsThread condaEnvs = new CondaEnvsThread(this);
        Thread thread = new Thread(condaEnvs.Recheck);
        thread.Start();
        thread.Join();
    }

    private void DeleteEnv(string? envName)
    {
        CondaEnvsThread condaEnvs = new CondaEnvsThread(this)
        {
            EnvName = envName
        };
        Thread thread = new Thread(condaEnvs.DeleteEnv);
        thread.Start();
        thread.Join();
    }

    private void AddEnv(string? envName, string? pythonVersion)
    {
        CondaEnvsThread condaEnvs = new CondaEnvsThread(this)
        {
            EnvName = envName,
            PythonVersion = pythonVersion
        };
        Thread thread = new Thread(condaEnvs.AddEnv);
        thread.Start();
        thread.Join();
    }

    private void recheckButton_Click(object sender, EventArgs e)
    {
        this.Recheck();
    }

    private void refreshEnvsButton_Click(object sender, EventArgs e)
    {
        this.EnvListRefresh();
    }

    private void Form1_Shown(object sender, EventArgs e)
    {
        this.Recheck();
        this.ShowMirrorsText();
        this.EnvListRefresh();
        this.envNameTextBox.Enabled = true;
        this.pythonVersionTextBox.Enabled = true;
        this.addEnvButton.Enabled = true;
    }

    private void removeEnv_Click(object sender, EventArgs e)
    {
        if (this.envsListBox.SelectedIndex == -1)
        {
            MessageBox.Show(
                "请选择要删除的虚拟环境", 
                "系统提示", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Information
            );
            return;
        }

        string? envName = this.envsListBox.GetItemText(this.envsListBox.SelectedItem);
        if (envName != null && envName.Trim().Length > 0)
        {
            envName = envName.Trim();
            DialogResult result = MessageBox.Show(
                $"确定要删除虚拟环境 {envName} 吗？此操作将无法恢复",
                "系统警告",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question
            );
            if (result == DialogResult.Yes)
            {
                this.DeleteEnv(envName);
                this.EnvListRefresh();
            }
        }
        else
        {
            MessageBox.Show(
                "未知虚拟环境名称", 
                "系统警告", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Warning
            );
        }
    }

    private void recheckMirrorsButton_Click(object sender, EventArgs e)
    {
        this.ShowMirrorsText();
    }

    private void addMirrorButton_Click(object sender, EventArgs e)
    {
        if (this.mirrorTextBox.Text.Trim().Length > 0)
        {
            this.AddMirrorUrl();
            this.ShowMirrorsText();
        }
    }

    private void removeMirrorButton_Click(object sender, EventArgs e)
    {
        if (this.mirrorsListBox.SelectedIndex == -1)
        {
            MessageBox.Show(
                "请选择要删除的镜像", 
                "系统提示", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Information
            );
            return;
        }

        string? mirrorUrl = this.mirrorsListBox.GetItemText(this.mirrorsListBox.SelectedItem);
        if (mirrorUrl != null && mirrorUrl.Trim().Length > 0)
        {
            mirrorUrl = mirrorUrl.Trim();
            DialogResult result = MessageBox.Show(
                $"确定要删除镜像 {mirrorUrl} 吗？此操作将无法恢复",
                "系统警告",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question
            );
            if (result == DialogResult.Yes)
            {
                this.RemoveMirrorUrl(mirrorUrl);
                this.ShowMirrorsText();
            }
        }
        else
        {
            MessageBox.Show(
                "未知镜像", 
                "系统警告", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Warning
            );
        }
    }

    private void addEnvButton_Click(object sender, EventArgs e)
    {
        string envName = this.envNameTextBox.Text.Trim();
        string pythonVersion = this.pythonVersionTextBox.Text.Trim();
        if (envName.Length > 0 && pythonVersion.Length > 0)
        {
            this.AddEnv(this.envNameTextBox.Text, this.pythonVersionTextBox.Text);
            this.EnvListRefresh();
            this.envNameTextBox.Text = "";
            this.pythonVersionTextBox.Text = "";
        }
        else
        {
            MessageBox.Show(
                "请输入环境名称与Python版本", 
                "系统警告", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Warning
            );
        }
    }

    private void ShowToolTip(MouseEventArgs e, ListBox control)
    {
        Size listBoxSize = control.ClientSize;
        if (e.X >= 0 && e.X <= listBoxSize.Width &&
            e.Y >= 0 && e.Y <= listBoxSize.Height)
        {
            int index = control.IndexFromPoint(e.Location);
            if (index > -1)
            {
                this.toolTip1.Active = true;
                this.toolTip1.SetToolTip(control, control.Items[index].ToString());
            }
            else
            {
                this.toolTip1.Active = false;
            }
        }
    }

    private void mirrorsListBox_MouseMove(object sender, MouseEventArgs e)
    {
        this.ShowToolTip(e, this.mirrorsListBox);
    }

    private void envsListBox_MouseMove(object sender, MouseEventArgs e)
    {
        this.ShowToolTip(e, this.envsListBox);
    }
}